﻿namespace CookieTerm
{
    using System;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Drawing;
    using System.Collections.Generic;
    using System.Collections;

    public partial class BookmarkEditor : Form
    {
        BookmarkManager bookmarkManager;
        string original;
        Dictionary<ColorBox, string> paletteBindingMapping;
        
        public bool changed;

        public BookmarkEditor(BookmarkManager manager)
        {
            InitializeComponent();

            this.bookmarkManager = manager;
            this.original = manager.Serialize();

            this.paletteBindingMapping = new Dictionary<ColorBox, string>
            {
                {this.blackBox, "Black"},
                {this.redBox, "Red"},
                {this.greenBox, "Green"}, 
                {this.yellowBox, "Yellow"}, 
                {this.blueBox, "Blue"}, 
                {this.magentaBox, "Magenta"},
                {this.cyanBox, "Cyan"},
                {this.whiteBox, "White"},

                {this.boldBlackBox, "BoldBlack"},
                {this.boldRedBox, "BoldRed"},
                {this.boldGreenBox, "BoldGreen"}, 
                {this.boldYellowBox, "BoldYellow"}, 
                {this.boldBlueBox, "BoldBlue"}, 
                {this.boldMagentaBox, "BoldMagenta"},
                {this.boldCyanBox, "BoldCyan"},
                {this.boldWhiteBox, "BoldWhite"},
            };

            this.bookmarkListBox.DataSource = this.bookmarkManager.Bookmarks;
            this.bookmarkListBox.DisplayMember = "Name";
            this.bookmarkListBox.ValueMember = "Name";

            this.displaySettingsListBox.DataSource = this.bookmarkManager.DisplaySettingsCollection;
            this.displaySettingsListBox.DisplayMember = "Name";
            this.displaySettingsListBox.ValueMember = "Name";

            // Create a new binding context because displaySettingsListBox and displaySettingsComboBox are using
            // the same data source, but they should have separate selected items.
            this.displaySettingsComboBox.BindingContext = new BindingContext();
            this.displaySettingsComboBox.DataSource = this.bookmarkManager.DisplaySettingsCollection;
            this.displaySettingsComboBox.DisplayMember = "Name";

            this.encodingComboBox.DataSource = DisplaySettings.SupportedEncodings;
        }

        private void bookmarkListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.bookmarkListBox.SelectedItem != null)
            {
                this.hostnameTextBox.DataBindings.Clear();
                this.hostnameTextBox.DataBindings.Add("Text", this.bookmarkListBox.SelectedItem, "Hostname");

                this.portUpDown.DataBindings.Clear();
                this.portUpDown.DataBindings.Add("Value", this.bookmarkListBox.SelectedItem, "Port");

                this.protocolComboBox.DataBindings.Clear();
                this.protocolComboBox.DataBindings.Add("SelectedItem", this.bookmarkListBox.SelectedItem, "Protocol");

                this.displaySettingsComboBox.DataBindings.Clear();
                this.displaySettingsComboBox.DataBindings.Add("SelectedItem", this.bookmarkListBox.SelectedItem, "DisplaySettings");
            }
        }

        private void displaySettingsListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.displaySettingsListBox.SelectedItem != null)
            {
                this.rowsTextBox.DataBindings.Clear();
                this.rowsTextBox.DataBindings.Add("Value", this.displaySettingsListBox.SelectedItem, "Rows");

                this.columnsTextBox.DataBindings.Clear();
                this.columnsTextBox.DataBindings.Add("Value", this.displaySettingsListBox.SelectedItem, "Columns");

                this.antiIdle.DataBindings.Clear();
                this.antiIdle.DataBindings.Add("Checked", this.displaySettingsListBox.SelectedItem, "AntiIdle");

                this.fontNameSizeLabel.DataBindings.Clear();
                this.fontNameSizeLabel.DataBindings.Add("DisplayBackColor", this.displaySettingsListBox.SelectedItem, "Black");
                this.fontNameSizeLabel.DataBindings.Add("DisplayForeColor", this.displaySettingsListBox.SelectedItem, "White");
                this.fontNameSizeLabel.DataBindings.Add("DisplayFont", this.displaySettingsListBox.SelectedItem, "Font", false, DataSourceUpdateMode.OnPropertyChanged);

                this.encodingComboBox.DataBindings.Clear();
                this.encodingComboBox.DataBindings.Add("SelectedItem", this.displaySettingsListBox.SelectedItem, "EncodingName");

                this.cursorColorBox.DataBindings.Clear();
                this.cursorColorBox.DataBindings.Add("Color", this.displaySettingsListBox.SelectedItem, "CursorColor", false, DataSourceUpdateMode.OnPropertyChanged);

                foreach (KeyValuePair<ColorBox, string> pair in this.paletteBindingMapping)
                {
                    pair.Key.DataBindings.Clear();
                    pair.Key.DataBindings.Add("Color", this.displaySettingsListBox.SelectedItem, pair.Value, false, DataSourceUpdateMode.OnPropertyChanged);
                }
            }
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            if (this.IsDirty())
            {
                DialogResult response = MessageBox.Show("Do you want to save the changes?", CookieTermAppSettings.ApplicationName, MessageBoxButtons.YesNoCancel);
                if (response == DialogResult.Cancel)
                {
                    e.Cancel = true;
                }
                else if (response == DialogResult.Yes)
                {
                    this.bookmarkManager.Save();
                }
                else if (response == DialogResult.No)
                {
                    this.bookmarkManager.Load();
                }
            }

            base.OnClosing(e);

        }

        private void saveButton_Click(object sender, EventArgs e)
        {
            Save();
        }

        private void closeButton_Click(object sender, EventArgs e)
        {
            Close();
        }

        bool IsDirty()
        {
            string current = this.bookmarkManager.Serialize();
            return !current.Equals(this.original);
        }

        void Save()
        {
            this.original = this.bookmarkManager.Serialize();
            this.bookmarkManager.Save();
            changed = true;
        }

        private void newBookmarkButton_Click(object sender, EventArgs e)
        {
            // TODO: Name generation mechanism
            Bookmark newBookmark = this.bookmarkManager.CreateBookmark("New Bookmark", "", 23, this.displaySettingsComboBox.SelectedValue.ToString(), "Default");
            ReloadFromDataSource(this.bookmarkListBox);
            this.bookmarkListBox.SelectedItem = newBookmark;
            this.bookmarkListBox.StartEditing();
        }

        private void newDisplaySettingsButton_Click(object sender, EventArgs e)
        {
            // TODO: Name generation mechanism
            DisplaySettings newDisplaySettings = this.bookmarkManager.CreateDisplaySettings("New Display Settings");
            ReloadFromDataSource(this.displaySettingsListBox);
            this.displaySettingsListBox.SelectedItem = newDisplaySettings;
            this.displaySettingsListBox.StartEditing();
        }

        private void removeBookmarkButton_Click(object sender, EventArgs e)
        {
            if (this.bookmarkListBox.SelectedItem != null)
            {
                this.bookmarkManager.RemoveBookmark((Bookmark)this.bookmarkListBox.SelectedItem);
                ReloadFromDataSource(this.bookmarkListBox);
                bookmarkListBox_SelectedIndexChanged(this, null);
            }
        }

        private void removeDisplaySettingsButton_Click(object sender, EventArgs e)
        {
            if (this.displaySettingsListBox.Items.Count <= 1)
            {
                MessageBox.Show("Cannot remove the last display settings", CookieTermAppSettings.ApplicationName, MessageBoxButtons.OK);
                return;
            }

            if (this.displaySettingsListBox.SelectedItem != null)
            {
                this.bookmarkManager.RemoveDisplaySettings((DisplaySettings)this.displaySettingsListBox.SelectedItem);
                ReloadFromDataSource(this.displaySettingsListBox);
                ReloadFromDataSource(this.displaySettingsComboBox);
                displaySettingsListBox_SelectedIndexChanged(this, null);
            }
        }

        public static void ReloadFromDataSource(ListControl control)
        {
            if (control.BindingContext != null && control.DataSource != null)
            {
                ((CurrencyManager)control.BindingContext[control.DataSource]).Refresh();
            }
        }
    }
}
